//==================================================================
//  Copyright (C) 2006  Davide Pasca
//
//  This library is free software; you can redistribute it and/or
//  modify it under the terms of the GNU Lesser General Public
//  License as published by the Free Software Foundation; either
//  version 2.1 of the License, or (at your option) any later version.
//
//  This library is distributed in the hope that it will be useful,
//  but WITHOUT ANY WARRANTY; without even the implied warranty of
//  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
//  Lesser General Public License for more details.
//
//  You should have received a copy of the GNU Lesser General Public
//  License along with this library; if not, write to the Free Software
//  Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
//==================================================================
///
///
///
//==================================================================

#include "stdafx.h"
#include <string.h>
#include "psys_stdgfx.h"
#include "m5d_scene.h"
#include "m5d_material.h"

//==================================================================
using namespace M5D;

//==================================================================
/// Texture class. 
//==================================================================
Texture::Texture( Scene *scenep, const char *namep, const TCHAR *filenamep,
				  ImageBase::LoadParams *load_paramsp ) :
	_scenep(scenep),
	_userdatap(NULL),
	_is_transparent(false),
	_filter_mode(PSYSGFX::TEXFILTERMODE_LINEAR),
	_s_addr_mode(PSYSGFX::TEXADDRMODE_WRAP),
	_t_addr_mode(PSYSGFX::TEXADDRMODE_WRAP)
{
	_name[0] = 0;
	_filename[0] = 0;

	if ( namep )
		SetName_( namep );

	if ( filenamep )
	{
		SetFileName( filenamep );

		ImageBase::LoadParams	params;
		if NOT( load_paramsp )
		{
			params._do_convert_truecolor = true;
			params._do_force_alpha = true;

			load_paramsp = &params;
		}

		TCHAR	buff[1600];
		
		bool is_absolute_pathname = (_tcsstr( filenamep, _T(":") ) != NULL);	// $$$ tweak !

		if ( is_absolute_pathname )
		{
			_tcscpy_s( buff, filenamep );
		}
		else
		{
			_tcscpy_s( buff, _scenep->GetLoadDataPath() );
			_tcscat_s( buff, filenamep );
		}

		_image_base.LoadAutodetect( buff, load_paramsp );

		if ( params._out_transparency_detected )
			_is_transparent = true;
	}
}

//==================================================================
Texture::Texture( Scene *scenep,
				  const char *namep,
				  Memfile &mf,
				  const TCHAR *filenamep,
				  PUtils::ImageBase::LoadParams *load_paramsp ) :
	_scenep(scenep),
	_userdatap(NULL),
	_is_transparent(false),
	_filter_mode(PSYSGFX::TEXFILTERMODE_LINEAR),
	_s_addr_mode(PSYSGFX::TEXADDRMODE_WRAP),
	_t_addr_mode(PSYSGFX::TEXADDRMODE_WRAP)
{
	_name[0] = 0;
	_filename[0] = 0;

	if ( namep )
		SetName_( namep );

	PASSERT( filenamep != NULL );
	if ( filenamep )
	{
		SetFileName( filenamep );
	}

	ImageBase::LoadParams	params;
	if NOT( load_paramsp )
	{
		params._do_convert_truecolor = true;
		params._do_force_alpha = true;

		load_paramsp = &params;
	}

	load_paramsp->SetTypeFromFilename( filenamep );
	_image_base.Load( mf, load_paramsp );

	if ( params._out_transparency_detected )
		_is_transparent = true;
}

//==================================================================
Texture::Texture( Scene *scenep, const char *namep, int w, int h, ImageBase::BaseFormat format ) :
	_scenep(scenep),
	_userdatap(NULL),
	_filter_mode(PSYSGFX::TEXFILTERMODE_LINEAR),
	_s_addr_mode(PSYSGFX::TEXADDRMODE_WRAP),
	_t_addr_mode(PSYSGFX::TEXADDRMODE_WRAP)
{
	_name[0] = 0;
	_filename[0] = 0;

	if ( namep )
		SetName_( namep );

	_image_base.Setup( format, w, h, NULL, 0 );
}

//==================================================================
Texture::~Texture(void)
{
//	if ( _scenep->_te_delete_cb )
//		_scenep->_te_delete_cb( _objlink.GetClient(), (Texture *)this );

	_scenep->unlinkTexture( this );
}

//==================================================================
void Texture::SetName_( const char *namep )
{
	strcpy_s( _name, namep );
}

//==================================================================
void Texture::SetFileName( const TCHAR *filenamep )
{
	_tcscpy_s( _filename, filenamep );
}

//==================================================================
/// Material class.
//==================================================================
Material::Material( Scene *scenep, const char *namep ) :
	_scenep(scenep),
	_userdatap(NULL),
	_texturep(NULL),
	_basic_blend(PSYSGFX::BASICBLEND_OPAQUE),
	_write_depth(true),
	_shininess(50.0f)
{
	_name[0] = 0;
	if ( namep )
		SetName( namep );

	SetDiffuseCol( 1, 1, 1, 1 );
	SetSpecularCol( 0.2f, 0.2f, 0.2f );
	SetEmissiveCol( 0, 0, 0 );

	_reflection = .2f;
	_flags = 0;

	_tex_crop_u1 = 0;
	_tex_crop_v1 = 0;
	_tex_crop_u2 = 0;
	_tex_crop_v2 = 0;
}

//==================================================================
Material::~Material()
{
	// dereference the texture
	SetTexture( NULL );

	_scenep->OnMaterialDelete( this );
}

//==================================================================
void Material::SetName( const char *namep )
{
	strcpy_s( _name, namep );
}

//==================================================================
void Material::SetTexture( M5D::Texture *texp )
{
	if ( texp )
	{
		if ( _texturep != texp )
		{
			_texturep = texp;
			_texturep->AddRef();
			//_scenep->OnMaterialModify( this );
		}
	}
	else
	{
		if ( _texturep != texp )
		{
			if ( _texturep->DecRef() )
			{
				SAFE_DELETE( _texturep );
			}
			//_scenep->OnMaterialModify( this );
		}
	}
}
